package edu.ustb.mis.dm.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class WClusterResult implements Serializable {
	private static final long serialVersionUID = 2417502274216200017L;

	/**
	 * 用来存储类中实例的名称（标识）
	 */
	private List<String> nameList = new ArrayList<String>();

	/**
	 * 类中实例属性的集合
	 */
	private Set<Integer> sameSet = new HashSet<Integer>();

	/**
	 * 类中实例属性的全集
	 */
	private Set<Integer> allSet = new HashSet<Integer>();

	/**
	 * 差异度
	 */
	private float dissimilarity = 0f;

	public WClusterResult() {
	}

	/**
	 * 构造函数,给定类标识和初始属性集
	 */
	public WClusterResult(final String docName, final Set<Integer> initSet) {
		this.nameList.add(docName);
		this.sameSet.addAll(initSet);
		this.allSet.addAll(initSet);
	}

	/**
	 * 添加新的元素入类 1、添加类标示 2、比对属性 3、修改差异度
	 * 
	 * @param classID
	 * @param attributes
	 * @param dissimilarity
	 */
	public void add(final String docName, final Set<Integer> attributes, final float dissimilarity) {
		this.nameList.add(docName);
		this.same(attributes);
		this.merge(attributes);
		this.dissimilarity = dissimilarity;
	}

	/**
	 * 添加新的元素名
	 * 
	 * @param classID
	 */
	public void addClass(final String docName) {
		this.nameList.add(docName);
	}

	/**
	 * 返回所有集合的属性数目
	 * 
	 * @return
	 */
	public int allSize() {
		return this.allSet.size();
	}

	/**
	 * 清空一个实例，包括类标识
	 */
	public void clear() {
		this.nameList.clear();
		this.clearSet();
	}

	/**
	 * 清空一个实例，只是属性集
	 */
	public void clearSet() {
		this.sameSet.clear();
		this.allSet.clear();
	}

	/**
	 * 与给定集合进行比对，得出相同的属性集合不同的属性集
	 * 
	 * @param set
	 */
	public void contrast(final Set<Integer> set) {
		this.same(set);
		this.merge(set);
	}

	/**
	 * 返回不同属性的数目
	 * 
	 * @return
	 */
	public float diffSize() {
		return this.allSize() - this.sameSize();
	}

	public Set<Integer> getAllSet() {
		return allSet;
	}

	public float getDissimilarity() {
		return dissimilarity;
	}

	public List<String> getNameList() {
		return nameList;
	}

	public Set<Integer> getSameSet() {
		return sameSet;
	}

	/**
	 * 数据初始化，给定属性及，没有类标识和名称，用于tmp存储
	 * 
	 * @param initSet
	 * @return
	 */
	public WClusterResult init(final Set<Integer> initSet) {
		this.sameSet.addAll(initSet);
		this.allSet.addAll(initSet);
		return this;
	}

	/**
	 * 初始化方法，没有类标识，给定sameSet和allSet,用于tmp存储
	 * 
	 * @param sameSet
	 * @param allSet
	 * @return
	 */
	public WClusterResult init(final Set<Integer> sameSet, final Set<Integer> allSet) {
		this.sameSet.addAll(sameSet);
		this.allSet.addAll(allSet);
		return this;
	}

	/**
	 * 数据初始化,给定类标识和一个初始属性集，将sameSet和allSet置为同一值
	 * 
	 * @param classID
	 * @param initSet
	 * @return
	 */
	public WClusterResult init(final String docName, final Set<Integer> initSet) {
		this.nameList.add(docName);
		this.sameSet.addAll(initSet);
		this.allSet.addAll(initSet);
		return this;
	}

	/**
	 * 计算全集
	 * 
	 * @param bitSet
	 */
	public void merge(final Set<Integer> set) {
		this.allSet.addAll(set);
	}

	/**
	 * 如添加新元素的话类内将达到属性数量
	 * 
	 * @return
	 */
	public int nextSize() {
		return size() + 1;
	}

	/**
	 * 删除类标识
	 * 
	 * @param classID
	 * @return
	 */
	public boolean removeClass(final String docName) {
		return this.nameList.remove(docName);
	}

	/**
	 * 计算相同属性
	 * 
	 * @param bitSet
	 */
	public void same(final Set<Integer> set) {
		this.sameSet.retainAll(set);
	}

	/**
	 * 返回相同属性集合的属性数目
	 * 
	 * @return
	 */
	public int sameSize() {
		return this.sameSet.size();
	}

	public void setAllSet(final Set<Integer> allSet) {
		this.allSet = allSet;
	}

	public void setDissimilarity(final float dissimilarity) {
		this.dissimilarity = dissimilarity;
	}

	public void setNameList(final List<String> nameList) {
		this.nameList = nameList;
	}

	public void setSameSet(final Set<Integer> sameSet) {
		this.sameSet = sameSet;
	}

	/**
	 * 类内元素数量
	 * 
	 * @return
	 */
	public int size() {
		return this.nameList.size();
	}
}
